package com.gyc.game.cchess;

import static com.gyc.game.cchess.model.ChessBoardBitPlanes.B_BISHOP;
import static com.gyc.game.cchess.model.ChessBoardBitPlanes.B_CANON;
import static com.gyc.game.cchess.model.ChessBoardBitPlanes.B_CAR;
import static com.gyc.game.cchess.model.ChessBoardBitPlanes.B_ELEPHANT;
import static com.gyc.game.cchess.model.ChessBoardBitPlanes.B_HORSE;
import static com.gyc.game.cchess.model.ChessBoardBitPlanes.B_KING;
import static com.gyc.game.cchess.model.ChessBoardBitPlanes.B_PAWN;
import static com.gyc.game.cchess.model.ChessBoardBitPlanes.IsRed;
import static com.gyc.game.cchess.model.ChessBoardBitPlanes.NOCHESS;
import static com.gyc.game.cchess.model.ChessBoardBitPlanes.R_BISHOP;
import static com.gyc.game.cchess.model.ChessBoardBitPlanes.R_CANON;
import static com.gyc.game.cchess.model.ChessBoardBitPlanes.R_CAR;
import static com.gyc.game.cchess.model.ChessBoardBitPlanes.R_ELEPHANT;
import static com.gyc.game.cchess.model.ChessBoardBitPlanes.R_HORSE;
import static com.gyc.game.cchess.model.ChessBoardBitPlanes.R_KING;
import static com.gyc.game.cchess.model.ChessBoardBitPlanes.R_PAWN;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Bitmap.Config;
import android.graphics.drawable.Drawable;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ProgressBar;

import com.gyc.game.cchess.model.ChessBoardBitPlanes;
import com.gyc.game.cchess.model.ChessMove;
import com.gyc.game.cchess.model.Eveluator;
import com.gyc.game.cchess.model.NegaScout_TT_HH;
import com.gyc.game.cchess.model.SearchEngineAbstract;
import com.gyc.game.cchess.model.SearchEngineAlphaBeta;

public class GameView extends View {

	public GameView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init();
	}

	public GameView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	public GameView(Context context) {
		super(context);
		init();
	}

	boolean m_bGameOver;

	ChessBoardBitPlanes cbp;// 10*9

	// MOVECHESS movingChess;

	ChessMove move;

	// CBitmap m_BoardBmp;
	// CImageList m_Chessman;

	int m_nBoardWidth;
	int m_nBoardHeight;

	private SearchEngineAbstract engine;

	private Bitmap qizibmp;

	private MainActivity MainActivity;

	private Paint blacklinepaint;

	public static int BORDERWIDTH = 30; // 棋盘(左右)边缘的宽度 15
	public static int BORDERHEIGHT = 26; // 棋盘(上下)边缘的高度 14
	public static int GRILLEWIDTH = 33; // 棋盘上每个格子的高度 39
	public static int GRILLEHEIGHT = 33; // 棋盘上每个格子的宽度 39

	public static String points = "帥車馬炮士象兵將車馬砲仕相卒";

	public final int message_start = 1;
	public final static int message_inter = 2;
	public final int message_end = 4;

	public final int message_move_not_found = 8;

	public void loadTile(int key, Drawable tile) {

		// mTileSize = getWidth()/mXTileCount;

		final Config argb_8888 = Bitmap.Config.ARGB_8888;

		int ht = tile.getIntrinsicHeight();// 资源实际的尺寸
		int wd = tile.getIntrinsicWidth();//

		// 504 36
		Bitmap bitmap = Bitmap.createBitmap(wd, ht, argb_8888);

		// imgheight = 36;
		chessHtwd = wd / 14; // 14个棋子图片

		Canvas canvas = new Canvas(bitmap);

		tile.setBounds(0, 0, wd, ht);

		tile.draw(canvas);

		this.qizibmp = bitmap;
	}

	int[][][] cords;// row*column*xy

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.view.View#onDraw(android.graphics.Canvas)
	 */
	@Override
	protected void onDraw(Canvas canvas) {
		Log.i("ondraw", "ondraw");

		// FIXME 这个都弄成 lazy-load
		this.m_nBoardHeight = this.getHeight();
		this.m_nBoardWidth = this.getWidth();

		int row, column;
		int xwidth = this.getWidth();
		int xheight = this.getHeight();

		Log.i("view-dimesnion", xwidth + "-" + xheight); // 320-455

		// public static byte BORDERWIDTH = 30; // 棋盘(左右)边缘的宽度 15
		// public static byte BORDERHEIGHT = 26; // 棋盘(上下)边缘的高度 14
		// public static byte GRILLEWIDTH = 33; // 棋盘上每个格子的高度 39
		// public static byte GRILLEHEIGHT = 33; // 棋盘上每个格子的宽度 39

		int hu = xheight / 10;// 9+1
		int wu = xwidth / 9;// 8+1

		if (hu > wu) {
			GRILLEWIDTH = wu;
			GRILLEHEIGHT = wu;

			BORDERHEIGHT = (xheight - GRILLEHEIGHT * 9) / 2;
			BORDERWIDTH = (xwidth - GRILLEWIDTH * 8) / 2;

		} else if (hu == wu) {
			GRILLEWIDTH = wu;
			GRILLEHEIGHT = wu;

			BORDERHEIGHT = (xheight - GRILLEHEIGHT * 9) / 2;
			BORDERWIDTH = (xwidth - GRILLEWIDTH * 8) / 2;

		} else {
			GRILLEWIDTH = hu;
			GRILLEHEIGHT = hu;

			BORDERHEIGHT = (xheight - GRILLEHEIGHT * 9) / 2;
			BORDERWIDTH = (xwidth - GRILLEWIDTH * 8) / 2;

		}

		// TODO 先把位置都算出来 放到二维数组中 以后不用算了
		if (cords == null) {
			cords = new int[10][9][2];

			for (row = 0; row < 10; row++) {
				cords[row] = new int[9][2];
				for (column = 0; column < 9; column++) {
					cords[row][column] = new int[2];
					cords[row][column][0] = row * GRILLEHEIGHT;
					cords[row][column][1] = column * GRILLEWIDTH;
				}
			}
		}

		// TODO 画棋盘
		blacklinepaint.setStrokeWidth(3);
		drawline(canvas, 0, 0, 9, 0);
		drawline(canvas, 0, 8, 9, 8);
		drawline(canvas, 0, 0, 0, 8);
		drawline(canvas, 9, 0, 9, 8);

		drawline(canvas, 4, 0, 4, 8);
		drawline(canvas, 5, 0, 5, 8);

		blacklinepaint.setStrokeWidth(2);
		drawline(canvas, 1, 0, 1, 8);
		drawline(canvas, 2, 0, 2, 8);
		drawline(canvas, 3, 0, 3, 8);
		drawline(canvas, 6, 0, 6, 8);
		drawline(canvas, 7, 0, 7, 8);
		drawline(canvas, 8, 0, 8, 8);

		drawline(canvas, 0, 1, 4, 1);
		drawline(canvas, 0, 2, 4, 2);
		drawline(canvas, 0, 3, 4, 3);
		drawline(canvas, 0, 4, 4, 4);
		drawline(canvas, 0, 5, 4, 5);
		drawline(canvas, 0, 6, 4, 6);
		drawline(canvas, 0, 7, 4, 7);

		drawline(canvas, 5, 1, 9, 1);
		drawline(canvas, 5, 2, 9, 2);
		drawline(canvas, 5, 3, 9, 3);
		drawline(canvas, 5, 4, 9, 4);
		drawline(canvas, 5, 5, 9, 5);
		drawline(canvas, 5, 6, 9, 6);
		drawline(canvas, 5, 7, 9, 7);

		drawline(canvas, 0, 3, 2, 5);
		drawline(canvas, 0, 5, 2, 3);

		drawline(canvas, 9, 3, 7, 5);
		drawline(canvas, 9, 5, 7, 3);

		// 棋子
		for (row = 0; row < 10; row++) {
			for (column = 0; column < 9; column++) {

				final byte chessNumber = cbp.getXY(row, column);

				if (chessNumber == NOCHESS) {
					continue;
				}

				final byte imageNumberForChess = getBitmapNumberForChessNumber(chessNumber);// [row][column]

				// 504=14*36 h36
				Rect src = new Rect();

				src.left = (imageNumberForChess - 1) * chessHtwd;
				src.right = imageNumberForChess * chessHtwd;
				src.top = 0;
				src.bottom = chessHtwd;

				int ptx = cords[row][column][1] + BORDERWIDTH;
				int pty = cords[row][column][0] + BORDERHEIGHT;

				Rect dst = new Rect();
				dst.left = ptx - GRILLEWIDTH / 2 + 4;
				dst.top = pty - GRILLEHEIGHT / 2 + 4;

				dst.right = dst.left + GRILLEWIDTH - 8;
				dst.bottom = dst.top + GRILLEHEIGHT - 8;

				// Log.i("src", src.toString());
				// Log.i("dst", dst.toString());

				Paint paint = new Paint();
				canvas.drawBitmap(qizibmp, src, dst, paint);

				/*
				 * int mcx = movingChessOrigin.x; int mcy = movingChessOrigin.y;
				 * // move out of for loop if (mcx == column && mcy == row) {
				 * dst.inset(-2, -2); final Paint paint2 = new Paint();
				 * paint2.setStyle(Paint.Style.STROKE);
				 * paint2.setColor(Color.RED); canvas.drawRect(dst, paint2); }
				 */
			}
		}

		if (move.fChessId != NOCHESS) {
			Log.i("move chess id:", "" + move.fChessId);

			int mcx = this.move.fRowColumn % 9;
			int mcy = this.move.fRowColumn / 9;

			int ptx = mcx * GRILLEWIDTH + BORDERWIDTH;
			int pty = mcy * GRILLEHEIGHT + BORDERHEIGHT;

			Rect dst = new Rect();
			dst.left = ptx - GRILLEWIDTH / 2 + 3;
			dst.top = pty - GRILLEHEIGHT / 2 + 4;

			dst.right = dst.left + GRILLEWIDTH - 6;
			dst.bottom = dst.top + GRILLEHEIGHT - 6;

			canvas.drawRect(dst, selectedChessPaint);
		}

		if (this.cbp.lastMove != null) {
			int mcx = this.cbp.lastMove.tRowColumn % 9;
			int mcy = this.cbp.lastMove.tRowColumn / 9;

			drawToken(canvas, mcx, mcy);
		}

		// dc.BitBlt(0, 0, m_nBoardWidth, m_nBoardHeight, &MemDC, 0, 0,
		// SRCCOPY);

		List<ChessMove> x = availableList;
		for (Iterator iterator = x.iterator(); iterator.hasNext();) {
			ChessMove chessMove = (ChessMove) iterator.next();
			int mcx = chessMove.tRowColumn % 9;
			int mcy = chessMove.tRowColumn / 9;

			int ptx = mcx * GRILLEWIDTH + BORDERWIDTH;
			int pty = mcy * GRILLEHEIGHT + BORDERHEIGHT;

			RectF dst = new RectF();
			dst.left = ptx - GRILLEWIDTH / 2 + 8;
			dst.top = pty - GRILLEHEIGHT / 2 + 10;

			dst.right = dst.left + GRILLEWIDTH - 16;
			dst.bottom = dst.top + GRILLEHEIGHT - 20;

			canvas.drawOval(dst, this.possbileMovePaint);
		}

		super.onDraw(canvas);
	}

	private void drawline(Canvas canvas, int fr, int fc, int tr, int tc) {
		int ptx = cords[fr][fc][1] + BORDERWIDTH;
		int pty = cords[fr][fc][0] + BORDERHEIGHT;

		int stopX = cords[tr][tc][1] + BORDERWIDTH;
		int stopY = cords[tr][tc][0] + BORDERHEIGHT;

		canvas.drawLine(ptx, pty, stopX, stopY, blacklinepaint);
	}

	private void drawToken(Canvas canvas, int mcx, int mcy) {
		int ptx = mcx * GRILLEWIDTH + BORDERWIDTH;
		int pty = mcy * GRILLEHEIGHT + BORDERHEIGHT;
		Rect dst = new Rect();
		dst.left = ptx - GRILLEWIDTH / 2 + 3;
		dst.top = pty - GRILLEHEIGHT / 2 + 4;

		dst.right = dst.left + GRILLEWIDTH - 6;
		dst.bottom = dst.top + GRILLEHEIGHT - 6;

		canvas.drawRect(dst, lastMovePaint);
	}

	/*
	 * public final static byte B_KING = 1; // 黑帅 public final static byte B_CAR
	 * = 2; // 黑车 public final static byte B_HORSE = 3;// 黑马 public final static
	 * byte B_CANON = 4; // 黑炮 public final static byte B_BISHOP = 5; // 黑士
	 * public final static byte B_ELEPHANT = 6; // 黑象 public final static byte
	 * B_PAWN = 7; // 黑卒 public final static byte B_BEGIN = B_KING; public final
	 * static byte B_END = B_PAWN; public final static byte R_KING = 8; // 红帅
	 * public final static byte R_CAR = 9; // 红车 public final static byte
	 * R_HORSE = 10; // 红马 public final static byte R_CANON = 11; // 红炮 public
	 * final static byte R_BISHOP = 12; // 红士 public final static byte
	 * R_ELEPHANT = 13; // 红象 public final static byte R_PAWN = 14; // 红兵
	 */
	static byte getBitmapNumberForChessNumber(final byte chessNumber) {
		byte result = 0;
		switch (chessNumber) {
		case B_BISHOP:// = 5; // 黑士
		case B_CANON:// = 4; // 黑炮
		case B_CAR:// = 2; // 黑车
		case B_ELEPHANT:// = 6; // 黑象
		case B_HORSE:// = 3;// 黑马
		case B_KING:// = 1; // 黑帅 0001
		case B_PAWN:// = 7; // 黑卒 0111
			result = chessNumber;
			break;

		case R_BISHOP:// = 0x50;
			result = 12;
			break;
		case R_CANON:// = 0x40;
			result = 11;
			break;
		case R_CAR:// = 0x20;
			result = 9;
			break;
		case R_ELEPHANT:// = 0x60;
			result = 13;
			break;
		case R_HORSE:// = 0x30;
			result = 10;
			break;
		case R_KING:// = 0x10;
			result = 8;
			break;
		case R_PAWN:// = 0x70;
			result = 14;
			break;
		default:
			break;
		}

		return result;
	}

	boolean calculating = false;
	private boolean turnSide;

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.view.View#onTouchEvent(android.view.MotionEvent)
	 */
	@Override
	public boolean onTouchEvent(MotionEvent event) {

		if (m_bGameOver) {
			return true;
		}

		float px = event.getX();
		float py = event.getY();

		int mx = getModx(px);
		int my = getMody(py);

		if (mx < 0 || mx > 8 || my < 0 || my > 9) {
			return true;
		}

		if (event.getAction() == MotionEvent.ACTION_DOWN) {

			if (calculating) {
				Log.i("onTouchEvent ", "pc calculating");
				return true;
			}

			try {
				onTouchDown(px, py, mx, my);
			} catch (CloneNotSupportedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}

		return true;
	}

	private Handler uiHandler = new Handler() {

		@Override
		public void handleMessage(Message msg) {

			if (msg.what == message_start) {
				Log.i("message", "message_start");

				GameView.this.MainActivity.tvHuman.setText("......思考中......");
				ProgressBar pb = (ProgressBar) GameView.this.MainActivity
						.findViewById(R.id.progress);
				pb.setMax(100);
				// setSecondaryProgress()
				pb.setProgress((pb.getProgress() + 10) % 100);
				pb.setSecondaryProgress((pb.getProgress() + 10) % 100);

			} else if (msg.what == message_inter) {
				// Log.i("message", "message_inter");

				// GameView.this.MainActivity.tvHuman.setText("思考中..");
				ProgressBar pb = (ProgressBar) GameView.this.MainActivity
						.findViewById(R.id.progress);
				pb.setMax(100);
				pb.setProgress((pb.getProgress() + 10) % 100);
				pb.setSecondaryProgress((pb.getProgress() + 10) % 100);

			} else if (msg.what == message_end) {
				Log.i("message", "message_end");

				String movestr = (String) msg.getData().get("move");
				if (movestr != null) {
					String[] splits = movestr.split(",");
					String fid = splits[0];
					String frc = splits[1];
					String tid = splits[2];
					String trc = splits[3];
					ChessMove move = new ChessMove();
					move.fChessId = Byte.parseByte(fid);
					move.fRowColumn = Byte.parseByte(frc);
					move.tChessId = Byte.parseByte(tid);
					move.tRowColumn = Byte.parseByte(trc);

					GameView.this.cbp.makeMove(move, true);

					if (IsGameOver(cbp)) {
						m_bGameOver = true;

						GameView.this.MainActivity.tvHuman.setText("   电脑 赢了");
					} else {

						GameView.this.MainActivity.tvHuman.setText("     看你的了");
					}

					ProgressBar pb = (ProgressBar) GameView.this.MainActivity
							.findViewById(R.id.progress);
					pb.setProgress(100);
					pb.setSecondaryProgress(100);

					calculating = false;
					GameView.this.invalidate();
				} else {
					m_bGameOver = true;
					ProgressBar pb = (ProgressBar) GameView.this.MainActivity
							.findViewById(R.id.progress);
					pb.setProgress(100);
					pb.setSecondaryProgress(100);
					GameView.this.MainActivity.tvHuman.setText("你赢了");

					calculating = false;
					GameView.this.invalidate();
				}

			}

			super.handleMessage(msg);
		}

	};

	private Thread aiThread;
	private Thread musicThread;

	private MediaPlayer stone;

	private List<ChessMove> availableList = new ArrayList<ChessMove>();

	private Paint lastMovePaint;

	private Paint selectedChessPaint;

	private Paint possbileMovePaint;

	private int chessHtwd;

	public void regret() {

		if (this.calculating) {
			return;
		} else {
			if (this.cbp.lastMove != null) {
				this.cbp.unMakeMove(this.cbp.lastMove);
			}
			if (this.cbp.lastMove != null) {
				this.cbp.unMakeMove(this.cbp.lastMove);
			}

			this.MainActivity.tvHuman.setText("     看你的了");

			this.move = new ChessMove();
			m_bGameOver = false;

			this.repaint();
		}

	}

	private void onTouchDown(float screenX, float screenY, int modX, int modY)
			throws CloneNotSupportedException {
		Log.i("ontouchdown ", screenX + "-" + screenY + "  :  " + modY + "-"
				+ modX);

		// 在移动中
		final byte x = cbp.getXY(modY, modX);

		Log.i(" pressed ", "" + x);

		if (move.fChessId != NOCHESS) {
			Log.i(" from CHESS ", "" + move.fChessId);

			turnSide = false;

			if (ChessBoardBitPlanes.IsValidMove(cbp, move.fRowColumn / 9,
					move.fRowColumn % 9, modY, modX)) {

				availableList.clear();

				playSound();

				move.tChessId = x;
				move.tRowColumn = (byte) (modY * 9 + modX);

				cbp.makeMove(move, true);

				Log.i(" == Move ", "" + move);

				move = new ChessMove();

				if (IsGameOver(cbp)) {
					m_bGameOver = true;

					this.MainActivity.tvHuman.setText("你赢了");
					return;
				}

				turnSide = true;

			} else {
				availableList.clear();

				if (IsRed(x)) {
					move.fRowColumn = (byte) (modY * 9 + modX);
					move.fChessId = x;

					availableList.addAll(this.cbp
							.getAvailableMoves(move.fRowColumn));
				}

			}

			repaint();

			if (turnSide == true) {
				if (aiThread != null && aiThread.isAlive()) {
					try {
						aiThread.interrupt();
					} catch (Exception e) {
					}
				}

				setAiThread();
				aiThread.start();

				this.calculating = true;
			}
		} else {
			// 第一次按下
			if (/*
				 * screenX > 0 && screenY > 0 && screenX < m_nBoardWidth &&
				 * screenY < m_nBoardHeight &&
				 */IsRed(x)) {
				availableList.clear();

				move.fRowColumn = (byte) (modY * 9 + modX);
				move.fChessId = x;

				availableList.addAll(this.cbp
						.getAvailableMoves(move.fRowColumn));

				repaint();

			}

		}
	}

	private void playSound() {
		musicThread = new Thread() {
			@Override
			public void run() {

				stone.seekTo(0);
				stone.start();
			}
		};

		musicThread.start();
	}

	// 原型：extern void *memcpy(void *dest, void *src, unsigned int count);
	/**
	 * @param dest
	 * @param src
	 * @param all
	 */
	public static void memcpy(byte[][] dest, byte[][] src, int all) {
		int dl = dest.length;
		int sl = src.length;

		for (int i = 0; i < dl && i < sl; i++) {
			System.arraycopy(src[i], 0, dest[i], 0, dest[i].length);
		}
	}

	public void init() {

		stone = MediaPlayer.create(getContext(), R.raw.stone);
		stone.start();

		this.MainActivity = (MainActivity) this.getContext();
		initPaints();

	}

	private void initPaints() {
		lastMovePaint = new Paint();
		lastMovePaint.setStyle(Paint.Style.STROKE);
		lastMovePaint.setColor(Color.BLUE);
		lastMovePaint.setStrokeWidth(2);

		selectedChessPaint = new Paint();
		selectedChessPaint.setStyle(Paint.Style.STROKE);
		selectedChessPaint.setColor(Color.BLACK);
		selectedChessPaint.setStrokeWidth(2);

		possbileMovePaint = new Paint();
		possbileMovePaint.setStyle(Paint.Style.STROKE);
		possbileMovePaint.setColor(Color.BLUE);
		possbileMovePaint.setStrokeWidth(3);

		blacklinepaint = new Paint();
		blacklinepaint.setStyle(Paint.Style.STROKE);
		blacklinepaint.setColor(Color.BLACK);
		blacklinepaint.setStrokeWidth(2);

	}

	public void startNewGame(int depth) {

		this.MainActivity.tvHuman.setText("");
		this.MainActivity.tvHuman.setTextColor(Color.BLUE);
		// this.MainActivity.tvHuman.setTextSize(16);

		if (this.aiThread != null && this.aiThread.isAlive()) {
			this.aiThread.interrupt();
			try {
				this.aiThread.join();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

		if (engine != null) {
			try {
				engine.destroy();
				engine = null;
			} catch (Exception e) {
				// TODO: handle exception
			}
		}
		
		// engine = new SearchEngineAlphaBeta();
		engine = new NegaScout_TT_HH();
		// engine = new NegaScout_TT_HHWithQuiese();

		cbp = new ChessBoardBitPlanes();
		engine.setChessBoardBitPlanes(cbp);
		engine.setEveluator(new Eveluator());
		engine.setSearchDepth(depth);
		engine.setUihandler(uiHandler);

		setAiThread();

		m_bGameOver = false;

		this.m_nBoardHeight = this.getHeight();
		this.m_nBoardWidth = this.getWidth();

		move = new ChessMove();

		repaint();

	}

	private void setAiThread() {

		this.aiThread = new Thread() {
			public void run() {
				long timecount = System.currentTimeMillis();
				Log
						.i("search good move start", System.currentTimeMillis()
								+ "");

				Message message = new Message();
				message.what = message_start;
				uiHandler.sendMessage(message);

				ChessMove best = new ChessMove();
				engine.setThread(this);

				best = engine.SearchAGoodMove(cbp);

				playSound();

				Log.i("search good move end", System.currentTimeMillis() + "");
				String sNodeCount = " Cost "
						+ (System.currentTimeMillis() - timecount) + " ms. "
						+ Eveluator.count + " Nodes were eveluated.";
				Log.i("search good move cost", sNodeCount);

				message = new Message();
				message.what = message_end;
				final Bundle bundle = new Bundle();
				if (best != null) {
					bundle.putString("move", best.toString());
				}
				message.setData(bundle);

				uiHandler.sendMessage(message);
			}
		};
	}

	public void repaint() {
		this.invalidate();
	}

	private int getMody(float py) {
		return (int) ((py - BORDERHEIGHT + GRILLEHEIGHT / 2) / GRILLEHEIGHT);
	}

	private int getModx(float px) {
		return (int) ((px - BORDERWIDTH + GRILLEWIDTH / 2) / GRILLEWIDTH);
	}

	public static boolean IsGameOver(ChessBoardBitPlanes position) {
		int row, column;
		boolean RedLive = false, BlackLive = false;

		for (row = 7; row < 10; row++)
			for (column = 3; column < 6; column++) {
				if (position.getXY(row, column) == B_KING) {
					BlackLive = true;
				} else if (position.getXY(row, column) == R_KING) {
					RedLive = true;
				}
			}

		for (row = 0; row < 3; row++)
			for (column = 3; column < 6; column++) {
				if (position.getXY(row, column) == B_KING) {
					BlackLive = true;
				} else if (position.getXY(row, column) == R_KING) {
					RedLive = true;
				}
			}

		if (RedLive && BlackLive)
			return false;
		else
			return true;

	}

	public void onPause() {
		try {
			if (this.aiThread.isAlive()) {
				this.aiThread.interrupt();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void onDestroy() {
		try {
			destroyAiThred();
		} catch (Exception e) {
		}

		try {
			destroyMusicThred();
		} catch (Exception e) {
		}

		try {
			engine.destroy();
		} catch (Exception e) {

		}

	}

	private void destroyMusicThred() {
		if (this.musicThread != null && this.musicThread.isAlive()) {
			this.musicThread.interrupt();
		}
		this.musicThread = null;
	}

	private void destroyAiThred() {
		if (this.aiThread != null && this.aiThread.isAlive()) {
			this.aiThread.interrupt();
		}
		this.aiThread = null;
	}

}
